package com.tianheng.modbus.util;

import lombok.extern.slf4j.Slf4j;

/**************************************************
 * copyright (c) 2020, peng.cao@tianheng-uestc.com All Rights Reserved.
 * created by peng.cao
 * date:       2020/7/3 0003
 * since:      1.0.0.1
 * description:
 *
 **************************************************/
@Slf4j
public class CRC16 {

        /**
         * 计算CRC16校验码
         *
         * @param data 需要校验的字符串
         * @return 校验码
         */
        public static String getCRC(String data) {
            data = data.replace(" ", "");
            int len = data.length();
            if (len % 2 == 0) {
                int num = len / 2;
                byte[] bytes = new byte[num];
                for (int i = 0; i < num; i++) {
                    int value = Integer.valueOf(data.substring(i * 2, 2 * (i + 1)), 16);
                    bytes[i] = (byte) value;
                }
                return getCRC(bytes);
            }
            return "0000";
        }

    /**
     *
     * @param bytes
     * @return
     */
    public static String getCRC(byte[] bytes) {
            //CRC寄存器全为1
            int CRC = 0x0000ffff;
            //多项式校验值
            int POLYNOMIAL = 0x0000a001;
            int i, j;
            for (i = 0; i < bytes.length; i++) {
                CRC ^= ((int) bytes[i] & 0x000000ff);
                for (j = 0; j < 8; j++) {
                    if ((CRC & 0x00000001) != 0) {
                        CRC >>= 1;
                        CRC ^= POLYNOMIAL;
                    } else {
                        CRC >>= 1;
                    }
                }
            }
            //结果转换为16进制
            String result = Integer.toHexString(CRC).toUpperCase();
            if (result.length() != 4) {
                StringBuffer sb = new StringBuffer("0000");
                result = sb.replace(4 - result.length(), 4, result).toString();
            }
            //交换高低位
//            return result.substring(2, 4) + result.substring(0, 2);
        return result;
        }


        public static void main(String[] args) {
            String s="010100000008";

            System.out.println(getCRC(s));


        }

}
